import React, { ReactNode, useEffect, useRef } from 'react';
import styled, { CSSProperties, css } from 'styled-components';
import BScroll from '@better-scroll/core'
import NavigationBar, { NavigationBarProps } from './NavigationBar';
import { useSelector } from 'react-redux';
import { RootState } from '../store';
import ResizeObserver from 'resize-observer-polyfill';

type Mode = 'default' | 'white'

const ModeWhiteBackground = css`
    background-color: ${(prop) => prop.theme.background.base};
`

const StatuBar = styled.div<{ height: string, mode?: Mode }>`
    z-index: 1;
    height: ${({ height }) => height};
    ${({ mode }) => mode === 'white' ? ModeWhiteBackground : undefined}
`

const SafeAreaBottom = styled.div<{ height: string }>`
    height: ${({ height }) => height};
`

const ModeWhite = css`
    background-color: ${(prop) => prop.theme.background.normal};
`
const Container = styled.div<{ mode?: Mode }>`
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    min-height: 0;
    position: relative;
    ${({ mode }) => mode === 'white' ? ModeWhite : undefined};
`

const NavigationBox = styled(NavigationBar) <{ mode?: Mode }>`
    z-index: 1;
    ${({ mode }) => mode === 'white' ? ModeWhiteBackground : undefined}
`

const Content = styled.div`

`

const Wapper = styled.div`
    z-index: 1;
    flex: 1;
    /* overflow-y: auto; */
    overflow-y: hidden;
    position: relative;
`

const ImgBox = styled.img`
    position: absolute;
    width: 100%;
    top: 0;
    left: 0;
    right: 0;
`

interface Props {
    children?: ReactNode;
    navigation?: NavigationBarProps;
    statu?: {
        className?: string;
        style?: CSSProperties;
    };

    className?: string;
    style?: CSSProperties;
    mode?: Mode;
    imagebackground?: string | { image: string, style: CSSProperties };
    hiddenSafeBottom?: boolean;
    contentClassName?: string;
}


const Controller: React.FC<Props> = ({ navigation, children, className, style, statu, imagebackground, mode, hiddenSafeBottom, contentClassName }) => {
    const safeArea = useSelector((state: RootState) => state.safeArea)
    const ref = useRef<HTMLDivElement>(null)
    const contentRef = useRef<HTMLDivElement>(null)
    const heightRef = useRef<number>(0)

    useEffect(() => {
        const dom = ref?.current;
        const content = contentRef?.current

        if (!dom || !content) {
            return
        }

        heightRef.current = content.clientHeight;

        const bs = new BScroll(dom, { bounce: true, click: true });
        bs.enable();

        const resizeObserver = new ResizeObserver(entries => {
            for (const entry of entries) {
                // entry.contentRect.height contains the new height of the observed element
                // console.info('Div height changed:', entry.contentRect.height);
                if (heightRef.current !== entry.contentRect.height) {
                    heightRef.current = entry.contentRect.height
                    // refrsh bs with the new height
                    bs?.refresh()
                }

            }
        });

        // Connect the ResizeObserver to the div
        resizeObserver.observe(content);

        return () => {
            bs.destroy()
            resizeObserver.disconnect()
        }

    }, [])

    return <Container
        className={className}
        style={style}
        mode={mode}
    >
        {/* use imagebackground will case some gesture problem in android */}
        {imagebackground &&
            <ImgBox
                src={typeof imagebackground === 'string' ? imagebackground : imagebackground.image}
                alt="bg"
                style={typeof imagebackground === 'string' ? undefined : imagebackground.style}
            />}
        <StatuBar
            style={statu?.style}
            className={statu?.className}
            height={safeArea.top}
            mode={mode}
        />
        {navigation && <NavigationBox
            {...navigation}
            mode={mode}
        />}
        <Wapper ref={ref}>
            <Content
                className={contentClassName}
                ref={contentRef}
            >
                {children}
            </Content>
        </Wapper>
        {!hiddenSafeBottom && <SafeAreaBottom height={safeArea.bottom} />}
    </Container>
}

export default Controller